﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;

namespace THO7_Team8
{
	public class CornerCoordinates
	{
		private Bitmap _bitmap;
		private int _height;
		private int _width;

		private readonly int redSearchValue = 255;
		private readonly int blueSearchValue = 255;
		private readonly int greenSearchValue = 255;

		public CornerCoordinates(Bitmap bitmap)
		{
			_bitmap = bitmap;
			_height = bitmap.Height;
			_width = bitmap.Width;
		}

		public Point[] GetCornerCoordinates()
		{
			Point mostLeftPixel = GetFirstPixelFromLeft();
			Point mostTopPixel = GetFirstPixelFromTop();
			Point mostRightPixel = GetFirstPixelFromRight();
			Point mostBottomPixel = GetFirstPixelFromLeft2();//GetFirstPixelFromBottom();
			//Point mostRightPixel = new Point(mostTopPixel.X, mostBottomPixel.Y);

			bool rotateLeft = false;

			//Kijk of het linker boven punt links van het rechter onder punt ligt
			if(mostTopPixel.X < mostBottomPixel.X)
			{
				rotateLeft = true;
			}
			//Kijk of het linker boven punt rechts van het rechter onder punt ligt
			else if(mostTopPixel.X > mostBottomPixel.X)
			{
				rotateLeft = false;
			}
			//Kijk of het linker boven punt op dezelfde x ligt als het rechter onder punt
			else if(mostTopPixel.X == mostBottomPixel.X)
			{
				rotateLeft = false;
				//Warning characters may end upside down. Maybe check for the blue part in the license plate?
			}

			Point topLeftPixel;
			Point topRightPixel;
			Point bottomLeftPixel;
			Point bottomRightPixel;

			if(rotateLeft)
			{
				topLeftPixel = mostTopPixel;
				topRightPixel = mostRightPixel;
				bottomRightPixel = mostBottomPixel;
				bottomLeftPixel = mostLeftPixel;
			}
			else
			{
				topLeftPixel = mostLeftPixel;
				topRightPixel = mostTopPixel;
				bottomRightPixel = mostRightPixel;
				bottomLeftPixel = mostBottomPixel;
			}

			Point[] points = new Point[4];
			points[0] = topLeftPixel;
			points[1] = topRightPixel;
			points[2] = bottomRightPixel;
			points[3] = bottomLeftPixel;
			return points;
		}

		public Point GetFirstPixelFromLeft()
		{
			BitmapData outputData = _bitmap.LockBits(new Rectangle(0, 0, _width, _height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
			int stride = outputData.Stride;
			Point pixel = new Point(-1, -1);
			bool pixelFound = false;
			unsafe
			{
				byte* optPnt = (byte*) outputData.Scan0;
				for(int x = 0; x < _width - 1 && !pixelFound; x++)
				{
					for(int y = 0; y < _height - 1 && !pixelFound; y++)
					{
						int pos = ((stride) * y) + (x * 3);
						if(optPnt[pos] == blueSearchValue && optPnt[pos + 1] == greenSearchValue && optPnt[pos + 2] == redSearchValue)
						{
							if(pixel.X == -1 && pixel.Y == -1)
							{
								pixel.X = x;
								pixel.Y = y;
								pixelFound = true;
							}
						}
					}
				}
			}
			_bitmap.UnlockBits(outputData);
			return pixel;
		}

		public Point GetFirstPixelFromLeft2()
		{
			BitmapData outputData = _bitmap.LockBits(new Rectangle(0, 0, _width, _height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
			int stride = outputData.Stride;
			Point pixel = new Point(-1, -1);
			bool pixelFound = false;
			unsafe
			{
				byte* optPnt = (byte*) outputData.Scan0;
				for(int x = 0; x < _width - 1 && !pixelFound; x++)
				{
					for(int y = _height - 1; y > 0 && !pixelFound; y--)
					{
						int pos = ((stride) * y) + (x * 3);
						if(optPnt[pos] == blueSearchValue && optPnt[pos + 1] == greenSearchValue && optPnt[pos + 2] == redSearchValue)
						{
							if(pixel.X == -1 && pixel.Y == -1)
							{
								pixel.X = x;
								pixel.Y = y;
								pixelFound = true;
							}
						}
					}
				}
			}
			_bitmap.UnlockBits(outputData);
			return pixel;
		}

		public Point GetFirstPixelFromTop()
		{
			BitmapData outputData = _bitmap.LockBits(new Rectangle(0, 0, _width, _height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
			int stride = outputData.Stride;
			Point pixel = new Point(-1, -1);
			bool pixelFound = false;
			unsafe
			{
				byte* optPnt = (byte*) outputData.Scan0;
				for(int y = 0; y < _height && !pixelFound; y++)
				{
					for(int x = _width; x > 0 && !pixelFound; x--)
					{
						int pos = ((stride) * y) + (x * 3);
						if(optPnt[pos] == blueSearchValue && optPnt[pos + 1] == greenSearchValue && optPnt[pos + 2] == redSearchValue)
						{
							if(pixel.X == -1 && pixel.Y == -1)
							{
								pixel.X = x;
								pixel.Y = y;
								pixelFound = true;
							}
						}
					}
				}
			}
			_bitmap.UnlockBits(outputData);
			return pixel;
		}

		public Point GetFirstPixelFromRight()
		{
			BitmapData outputData = _bitmap.LockBits(new Rectangle(0, 0, _width, _height), System.Drawing.Imaging.ImageLockMode.ReadWrite, _bitmap.PixelFormat);
			int stride = outputData.Stride;
			Point pixel = new Point(-1, -1);
			bool pixelFound = false;
			int pixelSize = 3;
			if(_bitmap.PixelFormat == PixelFormat.Format24bppRgb)
			{
				pixelSize = 24 / 8;
			}
			else if(_bitmap.PixelFormat == PixelFormat.Format32bppArgb)
			{
				pixelSize = 32 / 8;
			}
			unsafe
			{
				byte* optPnt = (byte*) outputData.Scan0;
				for(int x = _width - 1; x > 0 && !pixelFound; x--)
				{
					for(int y = _height - 1; y > 0 && !pixelFound; y--)
					{
						int pos = ((stride) * y) + (x * pixelSize);
						if(optPnt[pos] == blueSearchValue && optPnt[pos + 1] == greenSearchValue && optPnt[pos + 2] == redSearchValue)
						{
							if(pixel.X == -1 && pixel.Y == -1)
							{
								pixel.X = x;
								pixel.Y = y;
								pixelFound = true;
							}
						}
					}
				}
			}
			_bitmap.UnlockBits(outputData);
			return pixel;
		}

		public Point GetFirstPixelFromRight2()
		{
			BitmapData outputData = _bitmap.LockBits(new Rectangle(0, 0, _width, _height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
			int stride = outputData.Stride;
			Point pixel = new Point(-1, -1);
			bool pixelFound = false;
			unsafe
			{
				byte* optPnt = (byte*) outputData.Scan0;
				for(int x = _width; x > 0 && !pixelFound; x--)
				{
					for(int y = _height; y > 0 && !pixelFound; y--)
					{
						int pos = ((stride) * y) + (x * 3);
						if(optPnt[pos] == blueSearchValue && optPnt[pos + 1] == greenSearchValue && optPnt[pos + 2] == redSearchValue)
						{
							if(pixel.X == -1 && pixel.Y == -1)
							{
								pixel.X = x;
								pixel.Y = y;
								pixelFound = true;
							}
						}
					}
				}
			}
			_bitmap.UnlockBits(outputData);
			return pixel;
		}

		public Point GetFirstPixelFromBottom()
		{
			BitmapData outputData = _bitmap.LockBits(new Rectangle(0, 0, _width, _height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
			int stride = outputData.Stride;
			Point pixel = new Point(-1, -1);
			bool pixelFound = false;
			unsafe
			{
				byte* optPnt = (byte*) outputData.Scan0;
				for(int y = _height; y > 0 && !pixelFound; y--)
				{
					for(int x = 0; x < _width && !pixelFound; x++)
					{
						int pos = ((stride) * y) + (x * 3);
						if(optPnt[pos] == blueSearchValue && optPnt[pos + 1] == greenSearchValue && optPnt[pos + 2] == redSearchValue)
						{
							if(pixel.X == -1 && pixel.Y == -1)
							{
								pixel.X = x;
								pixel.Y = y;
								pixelFound = true;
							}
						}
					}
				}
			}
			_bitmap.UnlockBits(outputData);
			return pixel;
		}
	}
}